package com.dxp.controller;

import com.alibaba.druid.pool.DruidDataSource;
import com.apache.api.vo.ParamsVo;
import com.apache.api.vo.ResultMsg;
import com.apache.cache.service.impl.LoadCacheFactory;
import com.apache.client.StringUtil;
import com.apache.database.datasource.ConnctionData;
import com.apache.database.datasource.DynamicDataSource;
import com.apache.ius.controller.BaseAction;
import com.apache.rpc.common.LoadRpcService;
import com.apache.rpc.entity.RpcDatasource;
import com.apache.tools.ConfigUtil;
import com.apache.tools.DateUtils;
import com.apache.tools.StrUtil;
import com.apache.tools.UUIDUtil;
import com.dxp.utils.DatabaseUtils;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;

/**
 * @description: 数据库操作action
 * @author: Hou Dayu
 * @date: Created in 2020/10/29
 */
@Controller
@RequestMapping("/db/")
public class DatabaseAction extends BaseAction {

    /**
     * 获取数据表列表
     * @param datasource 数据源标识
     */
    @ResponseBody
    @RequestMapping(value = "browTable/{datasource}/", method = {RequestMethod.GET,RequestMethod.POST})
    public Object browTables(HttpServletRequest request, @PathVariable("datasource") String datasource) throws IOException {
        Map<String,Object> data = new HashMap();
        String jdbcUrl = request.getParameter("jdbcUrl");
        String driverClassName = request.getParameter("driverClassName");
        String jdbcUsername = request.getParameter("jdbcUsername");
        String jdbcPassword = request.getParameter("jdbcPassword");
        if(StrUtil.isNull(jdbcUrl) || StrUtil.isNull(driverClassName) || StrUtil.isNull(jdbcUsername) || StrUtil.isNull(jdbcPassword)){
            Object obj = LoadCacheFactory.getInstance().getCacheManager("").getCacheObjectByKey("rpc_datasource_" + datasource);
            if(null == obj) {
                return new ResultMsg("F","获取数据源失败");
            }
            JSONObject json = JSONObject.fromObject(obj);
            jdbcUrl = json.getString("jdbcUrl");
            driverClassName = json.getString("driverClassName");
            jdbcUsername = json.getString("jdbcUsername");
            jdbcPassword = json.getString("jdbcPassword");
        }
        Connection conn = DatabaseUtils.getInstance().getConnection(datasource,jdbcUrl,driverClassName,jdbcUsername,jdbcPassword);
        String dbType = DatabaseUtils.getInstance().getDataBaseType(driverClassName);
        String userName = null;
        if("oracle".equals(dbType)){
            userName = jdbcUsername;
        }
        List<String> list = DatabaseUtils.getInstance().getTables(conn,userName);
        data.put("flag","T");
        data.put("total",list.size());
        data.put("rows",list);
        return data;
    }

    /**
     * 获取表字段列表
     * @param datasource 数据源标识
     */
    @ResponseBody
    @RequestMapping(value = "tableWord/{datasource}/", method = {RequestMethod.GET,RequestMethod.POST})
    public Object tableWords(HttpServletRequest request, @PathVariable("datasource") String datasource) throws IOException {
        Map<String,Object> data = new HashMap();
        String tableName = request.getParameter("tableName");
        Object obj = LoadCacheFactory.getInstance().getCacheManager("").getCacheObjectByKey("rpc_datasource_" + datasource);
        if(null == obj) {
            return new ResultMsg("F","获取数据源失败");
        }
        JSONObject json = JSONObject.fromObject(obj);
        String jdbcUrl = json.getString("jdbcUrl");
        String driverClassName = json.getString("driverClassName");
        String jdbcUsername = json.getString("jdbcUsername");
        String jdbcPassword = json.getString("jdbcPassword");
        Connection conn = DatabaseUtils.getInstance().getConnection(datasource,jdbcUrl,driverClassName,jdbcUsername,jdbcPassword);
        String userName = "oracle".equals(DatabaseUtils.getInstance().getDataBaseType(driverClassName))?jdbcUsername:"";
        List<Map<String,String>> list = DatabaseUtils.getInstance().getTableColumns(conn,tableName,userName);
        data.put("flag","T");
        data.put("total",list.size());
        data.put("rows",list);
        return data;
    }

    /**
     * 生成数据表
     * @param datasource 数据源标识
     */
    @ResponseBody
    @RequestMapping(value = "createTable/{datasource}/", method = {RequestMethod.GET,RequestMethod.POST})
    public Object createTables(HttpServletRequest request, @PathVariable("datasource") String datasource){
        Object obj = LoadCacheFactory.getInstance().getCacheManager("").getCacheObjectByKey("rpc_datasource_" + datasource);
        if(null == obj) {
            return new ResultMsg("F","获取数据源失败");
        }
        JSONObject json = JSONObject.fromObject(obj);
        String jdbcUrl = json.getString("jdbcUrl");
        String driverClassName = json.getString("driverClassName");
        String jdbcUsername = json.getString("jdbcUsername");
        String jdbcPassword = json.getString("jdbcPassword");
        Connection conn = DatabaseUtils.getInstance().getConnection(datasource,jdbcUrl,driverClassName,jdbcUsername,jdbcPassword);
        List<String> sql = new ArrayList();
        String tableName = request.getParameter("tableName");
        String createTime = DateUtils.Now.fmt_yyyyMMdd_HHmmss();
        String userName = "oracle".equals(DatabaseUtils.getInstance().getDataBaseType(driverClassName))?jdbcUsername:"";
        if(StrUtil.isNull(tableName)) {
            Map<String, List<Map<String, String>>> tabs = DatabaseUtils.getInstance().getAllTableNamesMap(conn,userName);
            if (StrUtil.isEmpty(tabs) || tabs.isEmpty()) {
                return new ResultMsg("F", "数据表不存在,无法创建");
            }
            for (Map.Entry<String, List<Map<String, String>>> table : tabs.entrySet()) {
                String objName = StringUtil.toCamelNamed(table.getKey());
                String[] str = table.getKey().split("_");
                String tabPrefix = "";
                String sort_code = table.getKey();
                if (str.length > 1) {
                    tabPrefix = str[0];
                    sort_code = sort_code.substring(tabPrefix.length() - 1);
                }
                String sortId = UUIDUtil.getPrimaryKey();
                StringBuilder tabsql = new StringBuilder();
                tabsql.append("insert into pub_sort_info (sort_id,sort_code,sort_name,info_table_name,sort_status,sort_disable,sort_statistics,table_prefix,obj_name,sys_name,create_time)");
                tabsql.append(" values('" + sortId + "','" + sort_code + "','" + table.getKey() + "','" + table.getKey() + "','1','0','0','" + tabPrefix + "','" + objName + "','" + datasource + "','" + createTime + "')");
                sql.add(tabsql.toString());
                List<Map<String, String>> cloums = table.getValue();
                int count = cloums.size();
                for (int i = 0; i < count; i++) {
                    Map<String, String> cloum = cloums.get(i);
                    StringBuilder sb = new StringBuilder();
                    String metadataId = UUIDUtil.getPrimaryKey();
                    sb.append("insert into pub_metadata(metadata_id,sort_id,data_type,data_full_name,data_length,data_restrict,data_short_name,data_attr,reserved2,if_add,if_edit,if_list,if_search,create_time)");
                    sb.append(" values('" + metadataId + "','" + sortId + "','" + cloum.get("dataType") + "','" + cloum.get("dataShortName") + "','" + cloum.get("dataLength") + "','" + cloum.get("dataRestrict") + "','" + cloum.get("dataShortName") + "','" + cloum.get("dataAttr") + "','T','F','F','F','F','" + createTime + "')");
                    sql.add(sb.toString());
                }
            }
        } else {
            String objName = StringUtil.toCamelNamed(tableName);
            String[] str = tableName.split("_");
            String tabPrefix = "";
            String sort_code = tableName;
            if (str.length > 1) {
                tabPrefix = str[0];
                sort_code = sort_code.substring(tabPrefix.length() - 1);
            }
            String sortId = UUIDUtil.getPrimaryKey();
            StringBuilder tabsql = new StringBuilder();
            tabsql.append("insert into pub_sort_info (sort_id,sort_code,sort_name,info_table_name,sort_status,sort_disable,sort_statistics,table_prefix,obj_name,sys_name,create_time)");
            tabsql.append(" values('" + sortId + "','" + sort_code + "','" + tableName + "','" + tableName + "','1','0','0','" + tabPrefix + "','" + objName + "','" + datasource + "','" + createTime + "')");
            sql.add(tabsql.toString());
            List<Map<String, String>> cloums = DatabaseUtils.getInstance().getTableColumns(conn, tableName,userName);
            int count = cloums.size();
            for (int i = 0; i < count; i++) {
                Map<String, String> cloum = cloums.get(i);
                StringBuilder sb = new StringBuilder();
                String metadataId = UUIDUtil.getPrimaryKey();
                sb.append("insert into pub_metadata(metadata_id,sort_id,data_type,data_full_name,data_length,data_restrict,data_short_name,data_attr,reserved2,if_add,if_edit,if_list,if_search,create_time)");
                sb.append(" values('" + metadataId + "','" + sortId + "','" + cloum.get("dataType") + "','" + cloum.get("dataShortName") + "','" + cloum.get("dataLength") + "','" + cloum.get("dataRestrict") + "','" + cloum.get("dataShortName") + "','" + cloum.get("dataAttr") + "','T','F','F','F','F','" + createTime + "')");
                sql.add(sb.toString());
            }
        }
        if (!DynamicDataSource.getInstance().checkDataSource("plateform")) {
            Object objrpc = LoadCacheFactory.getInstance().getCacheManager("").getCacheObjectByKey("rpc_datasource_plateform");
            RpcDatasource rds = (RpcDatasource)objrpc;
            if (!DynamicDataSource.getInstance().addDataSource(rds.getSysEname(), rds.getDriverClassName(), rds.getJdbcUrl(), rds.getJdbcUsername(), rds.getJdbcPassword())) {
                return new ResultMsg("F","连接数据源[" + datasource + "]失败！");
            }
        }
        this.log.info("通过数据源[" + datasource + "]执行自定义SQL：" + sql);
        DruidDataSource dbDao = DynamicDataSource.getInstance().getDataSource("plateform");
        try {
            ConnctionData.getInstance().execute(dbDao.getConnection(), sql);
            ParamsVo psvo = new ParamsVo();
            psvo.setMethodKey("metadataAction");
            psvo.setParams("method","initCache");
            psvo.setParams("sysPass", ConfigUtil.getInstance().interfacePass());
            psvo.setParams("sysName", datasource);
            log.info("系统["+datasource+"]下所有[数据表信息]到缓存中...start !");
            LoadRpcService.service().doService("infoService","metadataAction","xml",psvo.getParams(),null);
        } catch (SQLException var6) {
            DynamicDataSource.getInstance().removeDataSource(datasource);
            return new ResultMsg("F","执行失败:" + var6.getMessage());
        }
        return new ResultMsg("T","数据表创建完成");
    }

}
